/**
 * 
 */
package com.toncen.samepms.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.toncen.samepms.common.AbstractTreeProvider;
import com.toncen.samepms.common.ITreeable;
import com.toncen.samepms.system.domain.Module;
import com.sky.common.json.JSONUtils;
import com.sky.common.lang.ClassUtils;
import com.sky.common.properties.PropertiesUtils;
import com.sky.common.string.StringUtils;

/**
 * DhtmlxTree辅助工具类
 * 
 * @author tch
 * 
 */
public class DhtmlxTreeUtils {
	/**
	 * @param type
	 *            树类型，参考tree.properties配置文件
	 * @param level
	 *            默认展开的层数，逐层加1，小于或者等于1的层数才会默认展开
	 * @param rootIds
	 *            根节点，无设置则显示全部树节点
	 * @param excludeIds
	 *            排除的节点，无设置则不排除任何节点
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static String getJSONString(String type, int level, String rootIds,
			String excludeIds) throws Exception {
		List<ITreeable> roots = getRootList(getTreeProvider(type).getRoots(),
				rootIds);
		String json = getJSONString(type, roots, level, excludeIds);
		return json;
	}

	/**
	 * 获取树数据提供者
	 * 
	 * @param type
	 * @return
	 * @throws Exception
	 */
	private static AbstractTreeProvider getTreeProvider(String type)
			throws Exception {
		String treeProviderClass = null;
		try {
			treeProviderClass = PropertiesUtils.getParameter(
					AbstractTreeProvider.FILE_TREE, type);
		} catch (Exception e) {
			throw new Exception("未设置树【" + type + "】，请与系统管理员联系!");
		}
		if (StringUtils.isEmpty(treeProviderClass)) {
			throw new Exception("未设置树【" + type + "】的数据提供者，请与系统管理员联系!");
		}
		Object treeProvider = ClassUtils.newInstance(treeProviderClass);
		if (!(treeProvider instanceof AbstractTreeProvider)) {
			throw new Exception("可操作数据权限提供者类型【"
					+ treeProvider.getClass().getName() + "】不正确，必须继承【"
					+ AbstractTreeProvider.class.getName() + "】，请与系统管理员联系!");
		}
		return (AbstractTreeProvider) treeProvider;
	}

	/**
	 * 获取指定节点开始的树
	 * 
	 * @param roots
	 * @param rootIds
	 * @return
	 * @throws Exception
	 */
	private static List<ITreeable> getRootList(List<ITreeable> roots,
			String rootIds) throws Exception {
		List<ITreeable> rootList = new ArrayList<ITreeable>();
		if (roots == null) {
			return rootList;
		}
		if (!StringUtils.isEmpty(rootIds)) {
			for (ITreeable child : roots) {
				if (isContain(child.getTreeId(), rootIds.split(",", -1))) {
					rootList.add(child);
					return rootList;
				} else {
					rootList.addAll(getRootList(child.getTreeChild(), rootIds));
				}
			}
			return rootList;
		} else {
			return roots;
		}
	}

	/**
	 * @param id
	 * @param ids
	 * @return
	 */
	private static boolean isContain(String id, String[] ids) {
		for (String i : ids) {
			if (id.equals(i)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @param type
	 * @param roots
	 * @param level
	 * @param excludeIds
	 * @return
	 * @throws Exception
	 */
	private static String getJSONString(String type, List<ITreeable> roots,
			int level, String excludeIds) throws Exception {
		Map<String, Object> JSONResult = new HashMap<String, Object>(5);
		JSONResult.put("id", 0);
		List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>(5);
		JSONResult.put("item", rows);
		Map<String, Object> childJSONObject;
		for (ITreeable root : roots) {
			childJSONObject = getJSONObject(type, root, level, excludeIds);
			if (childJSONObject != null && childJSONObject.size() != 0) {
				rows.add(childJSONObject);
			}
		}
		return JSONUtils.object2JSON(JSONResult);
	}

	/**
	 * @param type
	 * @param node
	 * @param level
	 * @param excludeIds
	 * @return
	 * @throws Exception
	 */
	private static Map<String, Object> getJSONObject(String type,
			ITreeable node, int level, String excludeIds) throws Exception {
		Map<String, Object> JSONResult = new HashMap<String, Object>(5);
		if (!StringUtils.isEmpty(excludeIds)) {// 排除id有设置
			if (isContain(node.getTreeId(), excludeIds.split(",", -1))) {
				return JSONResult;
			}
		}
		if (node.getTreeChild() != null) {
			while (node.getTreeChild().remove(null)) {// 移除空对象
			}
		}
		boolean isLeaf = node.getTreeChild() == null
				|| node.getTreeChild().size() == 0;// 是否叶子结点
		JSONResult.put("id", node.getTreeId());
		JSONResult.put("text", node.getTreeText());
		List<Map<String, Object>> linkUserdata = new ArrayList<Map<String, Object>>(
				5);
		Map<String, Object> typeMap = new HashMap<String, Object>(5);
		Map<String, Object> leafMap = new HashMap<String, Object>(5);
		Map<String, Object> levelMap = new HashMap<String, Object>(5);
		linkUserdata.add(typeMap);
		linkUserdata.add(leafMap);
		linkUserdata.add(levelMap);
		JSONResult.put("userdata", linkUserdata);// 添加自定义数据
		typeMap.put("name", "type");
		typeMap.put("content", node.getClass().getName());// 类型
		leafMap.put("name", "leaf");
		leafMap.put("content", isLeaf);// 是否叶子节点
		levelMap.put("name", "level");
		levelMap.put("content", level);// 层数
		if (isLeaf) {// 叶子结点

		} else {// 分支结点，则设置为打开状态
			if (level <= 1) {
				JSONResult.put("open", "1");
			}
		}
		List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>(5);
		JSONResult.put("item", rows);
		if (node.getTreeChild() != null) {
			Map<String, Object> childJSONObject;
			for (ITreeable child : node.getTreeChild()) {
				childJSONObject = getJSONObject(type, child,
						getNextLevel(level), excludeIds);
				if (childJSONObject != null && childJSONObject.size() != 0) {
					rows.add(childJSONObject);
				}
			}
		}
		return JSONResult;
	}

	/**
	 * 获取下一层数
	 * 
	 * @param level
	 * @return
	 */
	private static int getNextLevel(int level) {
		if (level != 0) {
			return ++level;
		} else {
			return level;
		}
	}

	public static void main(String[] args) throws Exception {
		String type = Module.class.getSimpleName();
		int level = 1;
		String rootId = "";
		String excludeId = "";
		System.out.println(getJSONString(type, level, rootId, excludeId));
	}
}
